package com.icost.directive.controller;

import com.icost.directive.entity.ActivationCode;
import com.icost.directive.enums.ProductEnum;
import com.icost.directive.request.ArkRequest;
import com.icost.directive.request.BaseRequest;
import com.icost.directive.request.ChatRequest;
import com.icost.directive.request.Message;
import com.icost.directive.response.ArkResponse;
import com.icost.directive.response.ChatCompletionResponse;
import com.icost.directive.response.GetShipResponse;
import com.icost.directive.response.ValidateCodeResponse;
import com.icost.directive.service.ActivationCodeService;
import com.icost.directive.util.DateUtils;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.Date;

import static com.icost.directive.util.DateUtils.YYYY_MM_DD_POINT;

/**
 * @author lujianwen@wsyxmall.com
 * @since 2025-08-15 14:32
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {
    private static final String API_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";
    private static final String API_KEY = "45d1fc10-5ecf-4f8f-bb94-87f2c0c7cc76";
    private static final String SYSTEM_PROMPT = """
            你是一个记账助手,
            理解并识别文字中体现的收支信息，如果存在多比交易，请识别文字中的汇总交易信息
            1.区分收支：明确是收入还是支出。
            2.提取金额：若为外币，按最新汇率换算成人民币。
            3.提取日期：无日期则记为%s。
            4.收支分类：从“收入”或“支出”中选择。
            5.生成备注：控制在十个字以内。
            输出格式（请只输出如下格式内容，不要输出其他说明性质的内容）：
            日期：yyyy.MM.dd
            时间：HH:mm
            收支：收入或支出
            金额：±金额数
            类别：根据收支类型选择支出类型（餐饮,三餐,零食,水果,蔬菜,购物,服饰,日用,数码,美妆,护肤,应用软件,住房,房租,维修,水电费,交通,公交,地铁,火车,飞机,打车,娱乐,医疗,门诊,住院,疫苗,体检,保险,通讯,汽车,学习,书籍,教育,办公,运动,社交,人情,家人,礼金,礼物,捐赠,育儿,宠物,旅行,度假,烟酒,彩票，如无合适分类选择日用），或者收入类型（工资,奖金,加班,福利,公积金,红包,兼职,副业,退税,投资,意外收入,其他），请从提供的选项中选择一项输出，不要输出或拼接其他内容
            备注：备注内容
            账户：从（）选择一项，如果文中无明确提及则输出
            """;
    private final ActivationCodeService activationCodeService;

    public ApiController(ActivationCodeService activationCodeService) {
        this.activationCodeService = activationCodeService;
    }

    public void explain(){

    }
    @PostMapping("/icost/ai")
    public ArkResponse callArkApi( @RequestBody ChatRequest userInput) {
        log.info("[callArkApi] request={}",userInput);
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(API_KEY);

        // system + user 消息
        String currDate = DateUtils.parseDateToStr(YYYY_MM_DD_POINT,new Date());
        Message systemMessage = new Message("system", SYSTEM_PROMPT.formatted(currDate));
        Message userMessage = new Message("user", userInput.getText());

        ArkRequest arkRequest = new ArkRequest("doubao-1-5-lite-32k-250115",
                Arrays.asList(systemMessage, userMessage));

        HttpEntity<ArkRequest> entity = new HttpEntity<>(arkRequest, headers);

        // 直接映射到 ArkResponse
        ResponseEntity<ChatCompletionResponse> response = restTemplate.exchange(
                API_URL, HttpMethod.POST, entity, ChatCompletionResponse.class);
        String content = response.getBody().getFirstMessageContent();
        //log.info("[callArkApi] content = {}",content);
        ArkResponse arkResponse = new ArkResponse();
        arkResponse.setSuccess(false);
        if(StringUtils.hasLength(content)){
            String[] lines = content.split("\n");
            String[] date = lines[0].split("：");
            arkResponse.setDate(date[1]);
            String[] time = lines[1].split("：");
            arkResponse.setTime(time[1]);
            String[] type = lines[2].split("：");
            arkResponse.setType(type[1]);
            String[] price = lines[3].split("：");
            arkResponse.setAmount(Math.abs(Double.valueOf(price[1])));
            String[] category = lines[4].split("：");
            arkResponse.setCategory(category[1]);
            String[] remark = lines[5].split("：");
            arkResponse.setNote(remark[1]);
            arkResponse.setRemark(remark[1]);
            arkResponse.setSuccess(true);
            if(arkResponse.getType().equals("收入")){
                arkResponse.setType("income");
            }else{
                arkResponse.setType("expense");
            }
        }
        log.info("[callArkApi] response = {}",arkResponse);
        return arkResponse;
    }
    @GetMapping("/get-shipping-info")
    public GetShipResponse getShipResponse(Integer productId){
        ActivationCode activationCode = activationCodeService.generateRandomCode(productId);
        GetShipResponse response = new GetShipResponse();
        response.setCode(activationCode.getCode());
        response.setSuccess(true);
        response.setMsg(ProductEnum.getMsg(productId));
        return response;
    }
    @GetMapping("/validate-and-use")
    public ValidateCodeResponse validateAndUse(@Valid BaseRequest baseRequest){
        boolean result = activationCodeService.validateAndUse(baseRequest);
        ValidateCodeResponse response = new ValidateCodeResponse();
        response.setSuccess(result);
        return response;
    }
}
